package logger

import (
	"github.com/CIPFZ/collector/internal/config"

	"go.uber.org/zap"
)

// Logger 日志器接口
type Logger interface {
	Debug(msg string, fields ...zap.Field)
	Info(msg string, fields ...zap.Field)
	Warn(msg string, fields ...zap.Field)
	Error(msg string, fields ...zap.Field)
	Panic(msg string, fields ...zap.Field)
	Fatal(msg string, fields ...zap.Field)

	Debugf(format string, args ...interface{})
	Infof(format string, args ...interface{})
	Warnf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
	Panicf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})

	Sync() error
	With(fields ...zap.Field) Logger
}

// zapLogger zap日志器实现
type zapLogger struct {
	logger *zap.Logger
}

// NewLogger 创建默认日志器
func NewLogger() (*zap.Logger, error) {
	devConfig := zap.NewDevelopmentConfig()
	devConfig.Level = zap.NewAtomicLevelAt(zap.InfoLevel)

	logger, err := devConfig.Build()
	if err != nil {
		return nil, err
	}

	return logger, nil
}

// NewLoggerWithConfig 根据配置创建日志器
func NewLoggerWithConfig(cfg config.LoggerConfig) (*zap.Logger, error) {
	var zapConfig zap.Config

	// 根据格式选择配置
	switch cfg.Format {
	case "json":
		zapConfig = zap.NewProductionConfig()
	case "console":
		zapConfig = zap.NewDevelopmentConfig()
	default:
		zapConfig = zap.NewDevelopmentConfig()
	}

	// 设置日志级别
	level, err := parseLogLevel(cfg.Level)
	if err != nil {
		return nil, err
	}
	zapConfig.Level = level

	// 设置输出目标
	if cfg.Output == "file" && cfg.File != "" {
		zapConfig.OutputPaths = []string{cfg.File}
		zapConfig.ErrorOutputPaths = []string{cfg.File}
	}

	logger, err := zapConfig.Build()
	if err != nil {
		return nil, err
	}

	return logger, nil
}

// parseLogLevel 解析日志级别
func parseLogLevel(level string) (zap.AtomicLevel, error) {
	switch level {
	case "debug":
		return zap.NewAtomicLevelAt(zap.DebugLevel), nil
	case "info":
		return zap.NewAtomicLevelAt(zap.InfoLevel), nil
	case "warn":
		return zap.NewAtomicLevelAt(zap.WarnLevel), nil
	case "error":
		return zap.NewAtomicLevelAt(zap.ErrorLevel), nil
	case "panic":
		return zap.NewAtomicLevelAt(zap.PanicLevel), nil
	case "fatal":
		return zap.NewAtomicLevelAt(zap.FatalLevel), nil
	default:
		return zap.NewAtomicLevelAt(zap.InfoLevel), nil
	}
}
